﻿using Newtonsoft.Json;
using System.Diagnostics;

namespace Wargame_V3_1
{
    public class TargetModel
    {
        private string _name;  // 目标名称，例如夺控点是City
        private Dictionary<string, string> _model;  // 目标模型，记录该目标的所有属性及属性类型
        private Dictionary<string, Dictionary<string, string>> _codeTexts;  // 代码文本，从代码文件中读取到的；CodeText["CalloutInteract"]["Type"]="cs", CodeText["CalloutInteract"]["Code"]="..."  （目标一般只有可能被动改变属性状态，而不会主动，因此不会有CalloutAction方法。
        private string[] _allowedFile = new string[] { "cs" };  // 支持输入的文件类型

        public string Name { get => _name; }
        public Dictionary<string, string> Model { get => _model; }
        public Dictionary<string, Dictionary<string, string>> CodeTexts { get => _codeTexts; }

        public TargetModel(string modelName, string modelPath)
        {
            _name = modelName;
            if (File.Exists(modelPath + @"\Model.json"))
            {
                Dictionary<string, string> oprMethods = new Dictionary<string, string>();
                using (StreamReader sr = new StreamReader(modelPath + @"\Model.json"))
                {
                    string data = sr.ReadToEnd();
                    Dictionary<string, object> allInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(data);
                    _model = JsonConvert.DeserializeObject<Dictionary<string, string>>(allInfo["Attributes"].ToString());
                    oprMethods = JsonConvert.DeserializeObject<Dictionary<string, string>>(allInfo["Methods"].ToString());
                }
                _codeTexts = new Dictionary<string, Dictionary<string, string>>();
                foreach (KeyValuePair<string, string> methodItem in oprMethods)
                {
                    string methodName = methodItem.Key;
                    string methodFile = methodItem.Value;
                    if (File.Exists(modelPath + "\\" + methodFile))
                    {
                        string codeType = methodFile.Split('.').Last();
                        if (_allowedFile.Contains(codeType))
                        {
                            string code = File.ReadAllText(modelPath + "\\" + methodFile);
                            _codeTexts.Add(methodName, new Dictionary<string, string>() { { "Type", codeType }, { "Code", code } });
                        }
                        else
                        {
                            Trace.TraceWarning($"暂时不支持此类型的代码：{methodFile}。");
                            continue;
                        }
                    }
                    else
                    {
                        Trace.TraceError($"输入的文件路径中缺少代码文件{methodFile}。");
                        throw new Exception($"输入的文件路径中缺少代码文件{methodFile}。");
                    }
                }
            }
            else
            {
                Trace.TraceError("输入的文件路径中缺少Model.json文件。");
                throw new Exception("输入的文件路径中缺少Model.json文件。");
            }
        }

        /// <summary>
        /// 判断当前类对象是否合法
        /// </summary>
        /// <returns></returns>
        public bool IsValid()
        {
            if (_name == null || _name == "") return false;
            if (_model == null || _model.Count == 0) return false;
            return true;
        }

        public Target CreateOprInstance(Dictionary<string, object> oprInfo)
        {
            Target tar = new Target(_model, oprInfo);
            foreach (KeyValuePair<string, Dictionary<string, string>> item in _codeTexts)
            {
                tar.SetMethod(item.Key, item.Value["Code"], item.Value["Type"]);
            }
            return tar;
        }
    }
}

